using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;

namespace visualtwimilar.Cache
{
  public class Cache
  {
    private const string DbFile = "firstProgram.db";
    private readonly ISession _session;
    private ITransaction _transaction;
    private readonly CacheContext _db;

    public Cache()
    {
      _session = CreateSessionFactory().OpenSession();
      _db = new CacheContext(_session);
    }

    ~Cache()
    {
      if (_session != null)
        _session.Dispose();
      if (_transaction != null)
        _transaction.Dispose();
    }

    public IEnumerable<string> Init(Func<string, IList<string>> func, string word)
    {
      CachedFunction resultFunction;

      var funcList = from function in _db.Functions
                     where (function.Name == func.Method.Name)
                     && (function.Param == word)
                     select function;
      if (funcList.Count() > 0)
      {
        resultFunction = funcList.First();
      }
      else
      {
        _transaction = _session.BeginTransaction();
        resultFunction = new CachedFunction
                           {
                             Name = func.Method.Name,
                             Param = word,
                             Results = new List<string>(func(word))
                           };
        _session.Save(resultFunction);
        _transaction.Commit();
      }
      return resultFunction.Results;
    }


    private static ISessionFactory CreateSessionFactory()
    {
      return Fluently.Configure()
        .Database(SQLiteConfiguration.Standard.UsingFile(DbFile))
        .Mappings(m =>
                  m.FluentMappings.AddFromAssemblyOf<App>())
        .ExposeConfiguration(BuildSchema)
        .BuildSessionFactory();
    }

    private static void BuildSchema(Configuration config)
    {
      if (!File.Exists(DbFile))
        new SchemaExport(config).Create(false, true);
    }
  }
}